using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace JumpyCat.bamboo
{
    class JCat
    {
        public static int LIFE_MAX = 3;
        Texture2D catImage;
        Texture2D lifeImage;

        Rect rect;

        private int lifeDrawPaddingX = 5;

        int asbVx;
        int asbVy;

        // position properties
        int xPos;
        int yPos;

        // velocity X, Y
        int vX;
        int vY;

        // life
        int life;
        public bool alive;

        // score
        public int score;
        public int hightScore;

        public int spinePosY;

        public bool savedHighscore;


        public JCat(Texture2D catImg, Texture2D lifeImg)
        {

            xPos = GameEngine.SCREEN_WIDTH / 2;
            yPos = GameEngine.SCREEN_HEIGHT / 2;
            life = LIFE_MAX;
            score = 0;

            asbVx = 8;
            asbVy = 12;

            Random randGenerator = new Random();

            int xDirectRandom = randGenerator.Next(4);
            vX = (xDirectRandom > 0) ? asbVx : (-asbVx);

            int yDirectRandom = randGenerator.Next(4);
            vY = (yDirectRandom > 0) ? asbVy : (-asbVy);

            this.catImage = catImg;
            this.lifeImage = lifeImg;

            this.rect = new Rect(this.xPos - 80, this.yPos - 60, 160, 120);
            this.spinePosY = GameEngine.SCREEN_HEIGHT - 80;
            this.alive = true;
            this.savedHighscore = false;

            hightScore = SaveHighScoreHelper.getHighScore();
        }

        public void increaseAsbVx()
        {
            System.Diagnostics.Debug.WriteLine("asbVx = " + asbVx);
            if (this.asbVx >= 18)
            {
                return;
            }
            this.asbVx = this.asbVx + 2;
            this.vX = (this.vX < 0) ? (-asbVx) : asbVx;
        }

        public void increaseAsbVy()
        {

            if (this.asbVy >= 36)
            {
                return;
            }
            System.Diagnostics.Debug.WriteLine("asbVy = " + asbVy);
            this.asbVy = this.asbVy + 4;
            this.vY = (this.vY < 0) ? (-asbVy) : asbVy;
        }

        // update function
        public void decreaseLife()
        {

            if (this.life > 0)
            {
                this.life -= 1;
            }

            if (this.life == 0)
            {
                alive = false;
            }

        }

        public void handleWhenTouchInCat(int x, int y)
        {
            if (this.isTouchInsideCat(x, y))
            {
                SimpleSoundManager.PlayTouchCatSound();

                float distanceX = this.xPos - x;

                if (distanceX > 0)
                {

                    vX = asbVx;

                }
                else
                {

                    vX = -asbVx;

                }

                vY = -asbVy;
            }
        }

        public void increaseScore(int score)
        {

            this.score += score;

        }

        public void saveHightScore()
        {
            if (!savedHighscore)
            {
                SaveHighScoreHelper.saveHighScore(this.score);
                this.savedHighscore = true;
            }
        }

        public bool isTouchInsideCat(int x, int y)
        {
            return (this.rect.isPointInRect(x, y));
        }

        public void updatePosition()
        {

            float oldYPos = yPos;

            xPos = xPos + vX;
            yPos = yPos + vY;

            this.rect = new Rect(this.xPos - 80, this.yPos - 30, 160, 120);

            if ((oldYPos > 300 && yPos <= 300))
            {
                this.increaseScore(20);
            }
            else
            {

                if ((oldYPos > 120 && yPos <= 120 && oldYPos < 300))
                {
                    this.increaseScore(30);
                }
            }

            if (this.collidWithLeftWall() || this.collidWithRightWall())
            {

                vX = -vX;

                if ((xPos - 80) < 0)
                {
                    xPos = 80;
                }
                else
                {
                    if ((xPos + 80) > GameEngine.SCREEN_WIDTH)
                    {
                        xPos = GameEngine.SCREEN_WIDTH - 80;
                    }
                }

            }

            if (this.collidWithTopWall() || this.collidWithBottomWall())
            {

                vY = -vY;

                if (this.collidWithBottomWall())
                {
                    SimpleSoundManager.PlayCatSound();
                    this.decreaseLife();
                }

                if ((yPos - 60) < 0)
                {
                    yPos = 60;
                }
                else
                {
                    if ((yPos + 60) > (this.spinePosY))
                    {
                        yPos = this.spinePosY - 60;
                    }
                }
            }

        }

        public bool collidWithLeftWall()
        {

            return ((xPos - 80) <= 0);

        }

        public bool collidWithRightWall()
        {

            return ((xPos + 80) >= GameEngine.SCREEN_WIDTH);
        }

        public bool collidWithTopWall()
        {

            return ((yPos - 60) <= 0);
        }

        public bool collidWithBottomWall()
        {

            return ((yPos + 60) >= (this.spinePosY));
        }

        // draw Function
        public void drawNumberLife(SpriteBatch g)
        {
            int xstart = 350;
            for (int i = 0; i < life; i++)
            {
                int xDrawPos = xstart + i * (40 + this.lifeDrawPaddingX);
                g.Draw(this.lifeImage, new Rectangle(xDrawPos, 10, (int)(lifeImage.Width * 1.2f), (int)(lifeImage.Height * 1.2f)), Color.White);

            }

        }

        public void drawScore(SpriteBatch g)
        {
            TextUtil.printString(g, 150, 10, "Best:" + hightScore, Font.SIZE_MEDIUM,Color.Blue);
            TextUtil.printString(g, 150, 40, "Score: " + this.score, Font.SIZE_MEDIUM, Color.Red);
        }


        public void paint(SpriteBatch g)
        {
            g.Draw(catImage,new Rectangle(this.rect.x,this.rect.y,this.rect.width,this.rect.height),Color.White);
        }
    }
}
